package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.commons.constants.Constants;
import com.tanhua.dubbo.api.*;
import com.tanhua.model.domain.Question;
import com.tanhua.model.dto.RecommentUserDto;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Userlike;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.NearUserVO;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.TodayBest;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.SimpleFormatter;

/**
 * @author Xiao
 * @date 2021/10/24
 */
@Service
public class TanhuaService {
    @DubboReference
    private RecommendUserApi recommendUserApi;
    @DubboReference
    private UserInfoApi userInfoApi;
    @DubboReference
    private QuestionApi questionApi;
    @Autowired
    private HuanXinTemplate huanXinTemplate;
    @DubboReference
    private UserLikeApi userLikeApi;
    @Value("${tanhua.default.recommend.users}")
    private String recommends;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private MessagesService messagesService;
    @DubboReference
    private UserLocationApi userLocationApi;
    @DubboReference
    private VisitorsApi visitorsApi;
    @DubboReference
    private FriendApi friendApi;

    /**
     * 今日佳人
     * @return
     */
    public TodayBest todayBest() {
        Long toUserId = UserHolder.getUserId();
        RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(toUserId);
        if (recommendUser == null) {
            recommendUser = new RecommendUser();
            recommendUser.setUserId(17L);
            recommendUser.setScore(99D);
        }
        Long userId = recommendUser.getUserId();
        UserInfo userInfo = userInfoApi.selectById(userId);
        return TodayBest.init(userInfo, recommendUser);
    }

    /**
     * 交友-推荐朋友
     * @param dto
     * @return
     */
    public PageResult recommendation(RecommentUserDto dto) {
        //调用recommendUserApi分页查询数据列表（PageResult -- RecommendUser）
        Long userId = UserHolder.getUserId();
        PageResult pageResult = recommendUserApi.queryRecommendUserList(
                dto.getPage(), dto.getPagesize(), userId);
        //获取分页中的RecommendUser数据列表
        List<RecommendUser> recommendUsers = (List<RecommendUser>) pageResult.getItems();
        //判断列表是否为空
        if (recommendUsers.size() == 0) {
            recommendUsers = recommendUserApi.getRandomRecommendUsers(pageResult.getPagesize());
            //return pageResult;
        }
        for (RecommendUser recommendUser : recommendUsers) {
            System.out.println(recommendUser);
        }
//        if (recommendUsers==null){
//            return pageResult;
//        }
        /*List<Long> userIds = new ArrayList<>();
        for (RecommendUser recommendUser : recommendUsers) {
            userIds.add(recommendUser.getUserId());
        }*/
        //提取所有推荐的用户id列表
        List<Long> userIds = CollUtil.getFieldValues(recommendUsers, "userId", Long.class);
        //构建查询条件，批量查询所有的用户详情
        UserInfo userInfo = new UserInfo();
        userInfo.setAge(dto.getAge());
        userInfo.setGender(dto.getGender());
        Map<Long, UserInfo> map = userInfoApi.selectByIdsAndCondition(userIds, userInfo);
        //循环推荐的数据列表，构建vo对象
        List<TodayBest> todayBests = new ArrayList<>();
        for (RecommendUser recommendUser : recommendUsers) {
            UserInfo userInfo1 = map.get(recommendUser.getUserId());
            if (userInfo1 != null) {
                TodayBest todayBest = TodayBest.init(userInfo1, recommendUser);
                todayBests.add(todayBest);
            }
        }
        //构造返回值
        pageResult.setItems(todayBests);
        return pageResult;
    }

    /**
     * 交友-佳人信息
     * @param userId
     * @return
     */
    public TodayBest personalInfo(Long userId) {
        //查看推荐数据
        Long toUserId = UserHolder.getUserId();
        RecommendUser recommendUser = recommendUserApi.getFateValue(userId, toUserId);
        //构造访客数据并保存
        if (!userId.equals(toUserId)) {
            Visitors visitors = new Visitors();
            visitors.setUserId(userId);
            visitors.setVisitorUserId(toUserId);
            visitors.setFrom("首页");
            visitors.setDate(System.currentTimeMillis());
            visitors.setVisitDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));
            visitors.setScore(recommendUser.getScore());
            visitorsApi.saveVisitors(visitors);
        }
        //查询佳人详情
        UserInfo userInfo = userInfoApi.selectById(userId);
        //构造佳人信息并返回
        return TodayBest.init(userInfo, recommendUser);
    }

    /**
     * 交友 -- 佳人信息 -- 聊一下 -- 查询陌生人问题
     * @param userId
     * @return
     */
    public String getStrangerQuestion(Long userId) {
        Question question = questionApi.selectByUserId(userId);
        return ObjectUtil.isEmpty(question) ? "你喜欢听音乐吗？" : question.getTxt();
    }

    /**
     * 交友 -- 佳人信息 -- 聊一下 -- 回复陌生人问题
     * @param userId
     * @param reply
     */
    public void replyStrangerQuestion(Long userId, String reply) {
        //设置消息内容
        Long currentUserId = UserHolder.getUserId();    //当前用户ID
        String huanXinId = Constants.HX_USER_PREFIX + currentUserId;    //当前用户环信账号
        String nickname = userInfoApi.selectById(currentUserId).getNickname();  //当前用户昵称
        String strangerQuestion = getStrangerQuestion(userId);  //对方设置的陌生人问题
        //将消息内容封装为Map集合
        Map<String, Object> map = new HashMap<>();
        map.put("userId", currentUserId);
        map.put("huanXinId", huanXinId);
        map.put("nickname", nickname);
        map.put("strangerQuestion", strangerQuestion);
        map.put("reply", reply);
        //将封装好的消息内容(Map)转为JSON字符串
        String content = JSON.toJSONString(map);
        //设置消息接收方账号
        String username = Constants.HX_USER_PREFIX + userId;
        //调用环信模板发送消息
        Boolean sendMsg = huanXinTemplate.sendMsg(username, content);
        if (!sendMsg) {
            throw new BusinessException(ErrorResult.error());
        }
    }

    /**
     * 探花-左滑右滑卡片列表
     * @return
     */
    public List<TodayBest> getCards() {
        Long userId = UserHolder.getUserId();
        //查询已喜欢/不喜欢的用户列表
        List<Userlike> userlikes = userLikeApi.getLikes(userId);
        //查询推荐列表，并排除已喜欢/不喜欢用户
        List<Long> likeUserIds = CollUtil.getFieldValues(userlikes, "likeUserId", Long.class);
        Integer count = 10;
        List<RecommendUser> recommendUsers = recommendUserApi.getRecommends(userId, likeUserIds, count);
        //如果推荐列表不存在，构造默认数据
        if (CollUtil.isEmpty(recommendUsers)) {
            recommendUsers = new ArrayList<>();
            String[] userIds = recommends.split(",");
            for (String id : userIds) {
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setUserId(Convert.toLong(id));
                recommendUser.setToUserId(userId);
                recommendUser.setScore(RandomUtil.randomDouble(60, 90));
                recommendUsers.add(recommendUser);
            }
        }
        //构造VO对象并返回
        List<Long> ids = CollUtil.getFieldValues(recommendUsers, "userId", Long.class);
        Map<Long, UserInfo> map = userInfoApi.selectByIdsAndCondition(ids, null);
        List<TodayBest> todayBests = new ArrayList<>();
        for (RecommendUser recommendUser : recommendUsers) {
            if (recommendUser.getUserId().equals(userId)) {
                continue;
            }
            UserInfo userInfo = map.get(recommendUser.getUserId());
            if (ObjectUtil.isNotEmpty(userInfo)) {
                todayBests.add(TodayBest.init(userInfo, recommendUser));
            }
        }
        return todayBests;
    }

    /**
     * 探花-喜欢(左滑)不喜欢(右滑)
     * @param likeUserId
     * @param direction true:love   false:unlove
     */
    public void love(Long likeUserId, Boolean direction) {
        //调用API，保存/更新喜欢数据
        Long userId = UserHolder.getUserId();
        Boolean operate = userLikeApi.saveOrUpdate(userId, likeUserId, direction);
        if (!operate) {
            throw new BusinessException(ErrorResult.error());
        }
        String loveKey = Constants.USER_LOVE_KEY + userId;
        String unLoveKey = Constants.USER_UNLOVE_KEY + userId;
        String keyValue = likeUserId.toString();
        if (direction) {
            //操作redis，写入喜欢的数据，删除不喜欢的数据
            redisTemplate.opsForSet().add(loveKey, keyValue);
            redisTemplate.opsForSet().remove(unLoveKey, keyValue);
            //判断是否双向喜欢-->如果双向喜欢，添加好友关系
            String key = Constants.USER_LOVE_KEY + keyValue;
            String value = userId.toString();
            Boolean isMember = redisTemplate.opsForSet().isMember(key, value);
            if (isMember) {
                messagesService.addContacts(likeUserId);
            }
        } else {
            //操作redis，写入不喜欢的数据，删除喜欢的数据
            redisTemplate.opsForSet().remove(loveKey, keyValue);
            redisTemplate.opsForSet().add(unLoveKey, keyValue);
            //删除环信好友关系
            Boolean deleteResult = huanXinTemplate.deleteContact(userId.toString(), likeUserId.toString());
            if (deleteResult) {
                //双向删除数据库好友关系
                friendApi.removeFriend(userId, likeUserId);
            }
        }
    }

    /**
     * 探花-搜附近
     * @param gender
     * @param distance
     * @return
     */
    public List<NearUserVO> search(String gender, Double distance) {
        Long userId = UserHolder.getUserId();
        List<Long> userIds = userLocationApi.search(userId, distance);
        if (CollUtil.isEmpty(userIds)) {
            return new ArrayList<>();
        }
        UserInfo userInfo = new UserInfo();
        userInfo.setGender(gender);
        Map<Long, UserInfo> map = userInfoApi.selectByIdsAndCondition(userIds, userInfo);
        List<NearUserVO> nearUserVOs = new ArrayList<>();
        for (Long id : userIds) {
            if (userId.equals(id)) {
                continue;
            }
            UserInfo info = map.get(id);
            if (ObjectUtil.isNotEmpty(info)) {
                nearUserVOs.add(NearUserVO.init(info));
            }
        }
        return nearUserVOs;
    }
}